home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 43.zip / Sources C- WorkDisk V.adf / ex / SecMap.c < prev   
C/C++ Source or Header  |  1987-02-15  |  12KB  |  344 lines

  1. /*  :ts=8 bk=0 
  2.  * Disk mapper.  Uses trackdisk.device to grab and read sector bitmap 
  3.  * to discover what's allocated, then displays a (hopefully) pretty picture 
  4.  * showing disk useage. 
  5.  * 
  6.  * Crufted together by Leo Schwab while desperately bored.  8606.8 
  7.  * Turned into something working for the Manx compiler.  8607.23 
  8.  */ 
  9.  
  10. #include <exec/types.h> 
  11. #include <exec/memory.h> 
  12. #include <intuition/intuition.h> 
  13. #include <libraries/dos.h> 
  14. #include <devices/trackdisk.h> 
  15.  
  16. #define REV             0L 
  17. #define BLOCKSIZE       TD_SECTOR 
  18. #define NUMBLOCKS       (NUMCYLS * NUMHEADS * NUMSECS) 
  19. #define ROOTBLOCK       (NUMBLOCKS / 2) 
  20. #define BITMAPINDEX     79 
  21. #define NUMLONGS        (NUMBLOCKS / 32) 
  22. #define XX              6L 
  23. #define YY              6L 
  24. #define XOFF            30L 
  25. #define YOFF            25L 
  26. #define BRKOVER         91L     /*  11 * YY + YOFF  */ 
  27. #define SEP             6 
  28.  
  29. extern void     *OpenLibrary(), *OpenDevice(), *OpenWindow(), *AllocMem(), 
  30.                 *Lock(), *Info(), *CreatePort(), *CreateExtIO(); 
  31. extern long     TextLength(); 
  32.  
  33.  
  34. struct NewWindow windef = { 
  35.         0, 0, 640, 180, 
  36.         -1, -1, 
  37.         CLOSEWINDOW, 
  38.         WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | ACTIVATE, 
  39.         NULL, NULL, 
  40.         (UBYTE *) "Disk Allocation Map ", 
  41.         NULL, NULL, 0, 0, 0, 0, 
  42.         WBENCHSCREEN 
  43. }; 
  44.  
  45. struct IntuiText ok = { 
  46.         AUTOFRONTPEN, AUTOBACKPEN, 
  47.         AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE, 
  48.         AUTOITEXTFONT, 
  49.         (UBYTE *) "OK", 
  50.         AUTONEXTTEXT 
  51. }; 
  52.  
  53. struct IntuiText errmsg = { 
  54.         AUTOFRONTPEN, AUTOBACKPEN, 
  55.         AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE, 
  56.         AUTOITEXTFONT, 
  57.         NULL,   /*  Gets filled in later  */ 
  58.         AUTONEXTTEXT 
  59. }; 
  60.  
  61. struct Window   *win; 
  62. struct RastPort *rp; 
  63. struct InfoData *id; 
  64. struct IOExtTD  *diskreq; 
  65. struct MsgPort  *diskport; 
  66. ULONG           diskchangecount, lok, *diskbuffer; 
  67. void            *IntuitionBase, *GfxBase; 
  68.  
  69.  
  70. main (ac, av) 
  71. char *av[]; 
  72.         long k, x, y; 
  73.         int unit, bmsect, free = NUMBLOCKS-2; 
  74.         short i, n, l; 
  75.         char buf[80]; 
  76.  
  77.         if (!ac) {      /*  Run from workbench (ick!)  */ 
  78.                 /*  I'll make this part better someday.....  */ 
  79.                 strcpy (buf, "df0:"); 
  80.         } else {        /*  Run from CLI (thank you)  */ 
  81.                 if (ac == 1) { 
  82.                         printf ("Drive specifier: "); 
  83.                         gets (buf); 
  84.                 } else 
  85.                         strcpy (buf, av[1]); 
  86.         } 
  87.  
  88.         openstuff (); 
  89.  
  90.         if (!(lok = Lock (buf, ACCESS_READ))) 
  91.                 die ("Can't obtain lock for specified device."); 
  92.  
  93.         if (!(id = AllocMem ((long) sizeof (*id), MEMF_CLEAR))) 
  94.                 die ("Can't get InfoData memory."); 
  95.  
  96.         if (!Info (lok, id)) 
  97.                 die ("Call to Info() failed."); 
  98.  
  99.         if (id -> id_DiskType == ID_NO_DISK_PRESENT) 
  100.                 die ("No disk in drive."); 
  101.  
  102.         unit = id -> id_UnitNumber; 
  103.         FreeMem (id, (long) sizeof (*id));  id = NULL; 
  104.         opendisk (unit); 
  105.         MotorOn (); 
  106.         GetSector ((long) ROOTBLOCK); 
  107.         bmsect = diskbuffer[BITMAPINDEX]; 
  108.         GetSector ((long) bmsect); 
  109.         MotorOff (); 
  110.  
  111.         /* 
  112.          * At this point, we now have the bitmap in the disk buffer. 
  113.          * This is what the first longword in the bitmap represents: 
  114.          * 
  115.          *      333322222222221111111111 
  116.          *      32109876543210987654321098765432        Sector # 
  117.          *      -------------------------------- 
  118.          *      10100101001010010010010001010011        Longword 
  119.          *      MSB                          LSB 
  120.          * 
  121.          * If the bit is set, the sector is free. 
  122.          * 
  123.          * Sectors 0 and 1 contain the boot block.  Thus, the DOS is not 
  124.          * allowed to walk on them, and they are permanently allocated. 
  125.          * However, the bitmap does not reflect this i.e. the bitmap starts 
  126.          * at sector 2, which is indicated by bit 0, longword 1.  This means 
  127.          * we have to offset everything by two.  Can you say "crock?" 
  128.          * 
  129.          * Actually, I suppose this is good, since it prevents some would-be 
  130.          * smart person from un-allocating those sectors and messing things 
  131.          * up badly. 
  132.          * 
  133.          * Bitmap starts at longword 1; longword 0 appears to be some kind 
  134.          * of significant garbage (checksum?) 
  135.          * 
  136.          * For more info on how I found the bitmap sector, consult the DOS 
  137.          * Technical Reference Manual, p. 1-1 - 1-2 
  138.          */ 
  139.  
  140.         SetAPen (rp, 3L); 
  141.         RectFill (rp, XOFF, YOFF, XX+XOFF, YY+YY+YOFF); /*  Show first two  */ 
  142.         for (i=1; i<=NUMLONGS; i++) { 
  143.                 k = diskbuffer[i]; 
  144.                 for (n=0; n<32; n++) 
  145.                         /*  Bits progress from low to high order  */ 
  146.                         if (i<NUMLONGS || n<30) {       /*  Ignore last two  */ 
  147.                                 if (~k & 1) { 
  148.                                         /*  Perform icky conversion  */ 
  149.                                         free--; 
  150.                                         l = (i-1 << 5) + n + 2; 
  151.                                         x = (l / 22) * XX + XOFF; 
  152.                                         y = (l % 22) * YY + YOFF; 
  153.                                         if (y >= BRKOVER) 
  154.                                                 y += SEP; 
  155.                                         RectFill (rp, x, y, x+XX-1, y+YY-1); 
  156.                                 } 
  157.                                 k >>= 1; 
  158.                         } 
  159.         } 
  160.  
  161.         /*  Draw grid so we can see  */ 
  162.         SetAPen (rp, 1L); 
  163.         for (x=XOFF; x<=80*XX+XOFF; x += XX) { 
  164.                 Move (rp, x, YOFF); 
  165.                 Draw (rp, x, YOFF+11*YY); 
  166.                 Move (rp, x, BRKOVER+SEP); 
  167.                 Draw (rp, x, BRKOVER+SEP+11*YY); 
  168.         } 
  169.         for (y=0; y<=11*YY; y += YY) { 
  170.                 Move (rp, XOFF, y+YOFF); 
  171.                 Draw (rp, XOFF+80*XX, y+YOFF); 
  172.                 Move (rp, XOFF, y+SEP+BRKOVER); 
  173.                 Draw (rp, XOFF+80*XX, y+SEP+BRKOVER); 
  174.         } 
  175.  
  176.         /*  Draw map markings  */ 
  177.         Move (rp, XOFF+XX/2, YOFF);       Draw (rp, XOFF+XX/2, YOFF-3); 
  178.         Move (rp, XOFF+80*XX-XX/2, YOFF); Draw (rp, XOFF+80*XX-XX/2, YOFF-3); 
  179.         Move (rp, XOFF, YOFF+YY/2);       Draw (rp, XOFF-3, YOFF+YY/2); 
  180.         Move (rp, XOFF, YOFF+YY*10+YY/2); Draw (rp, XOFF-3, YOFF+YY*10+YY/2); 
  181.         Move (rp, XOFF-1, YOFF-3);        Text (rp, "0", 1L); 
  182.         Move (rp, XOFF+79*XX-1, YOFF-3);  Text (rp, "79", 2L); 
  183.         Move (rp, XOFF-12, YOFF+6);       Text (rp, "0", 1L); 
  184.         Move (rp, XOFF-20, YOFF+11*YY);   Text (rp, "10", 2L); 
  185.  
  186.         /*  Do labels  */ 
  187.         sprintf (buf, "Bitmap on sector %d", bmsect); 
  188.         Move (rp, XOFF, 176L); 
  189.         Text (rp, buf, (long) strlen (buf)); 
  190.         sprintf (buf, "Sectors free: %d", free); 
  191.         Move (rp, 250L, 176L); 
  192.         Text (rp, buf, (long) strlen (buf)); 
  193.         sprintf (buf, "Allocated: %d", (int) NUMBLOCKS-free); 
  194.         Move (rp, 450L, 176L); 
  195.         Text (rp, buf, (long) strlen (buf)); 
  196.         Move (rp, 520L, 60L); 
  197.         Text (rp, "Surface 0", 9L); 
  198.         Move (rp, 520L, 132L); 
  199.         Text (rp, "Surface 1", 9L); 
  200.  
  201.         /*  Wait for close gadget  */ 
  202.         Wait (1L << win -> UserPort -> mp_SigBit); 
  203.         closestuff (); 
  204.  
  205.  
  206. openstuff () 
  207.         if (!(IntuitionBase = OpenLibrary ("intuition.library", REV))) { 
  208.                 /* 
  209.                  * If we can't open Intuition, then we can't use 
  210.                  * AutoRequest () 
  211.                  */ 
  212.                 printf ("Intuition failed; you'll have to use logic.\n"); 
  213.                 closestuff (); 
  214.                 exit (100); 
  215.         } 
  216.  
  217.         if (!(GfxBase = OpenLibrary ("graphics.library", REV))) { 
  218.                 printf ("Art shop closed.\n"); 
  219.                 closestuff (); 
  220.                 exit (100); 
  221.         } 
  222.  
  223.         if (!(win = OpenWindow (&windef))) { 
  224.                 printf ("Window painted shut.\n"); 
  225.                 closestuff (); 
  226.                 exit (100); 
  227.         } 
  228.         rp = win -> RPort; 
  229.  
  230. opendisk (unit) 
  231. int unit; 
  232.         long err; 
  233.         char *buf[80]; 
  234.  
  235.         if (!(diskport = CreatePort (NULL, NULL))) 
  236.                 die ("No port."); 
  237.  
  238.         if (!(diskreq = CreateExtIO (diskport, (long) sizeof (*diskreq)))) 
  239.                 die ("Can't make IO block."); 
  240.  
  241.         if (err = OpenDevice (TD_NAME, (long) unit, diskreq, NULL)) { 
  242.                 sprintf (buf, "Can't get at disk; err = %ld.", err); 
  243.                 DeleteExtIO (diskreq, (long) sizeof (*diskreq)); 
  244.                 diskreq = NULL; 
  245.                 die (buf); 
  246.         } 
  247.  
  248.         if (!(diskbuffer = AllocMem (BLOCKSIZE, MEMF_CLEAR | MEMF_CHIP))) 
  249.                 die ("Can't allocate disk buffer."); 
  250.  
  251.         diskreq -> iotd_Req.io_Command = TD_CHANGENUM; 
  252.         DoIO (diskreq); 
  253.         diskchangecount = diskreq -> iotd_Req.io_Actual; 
  254.  
  255. closestuff () 
  256.         if (lok) 
  257.                 UnLock (lok); 
  258.         if (diskreq) { 
  259.                 CloseDevice (diskreq); 
  260.                 DeleteExtIO (diskreq, (long) sizeof (*diskreq)); 
  261.         } 
  262.  
  263.         if (diskbuffer) 
  264.                 FreeMem (diskbuffer, (long) BLOCKSIZE); 
  265.         if (id) 
  266.                 FreeMem (id, (long) sizeof (*id)); 
  267.         if (diskport) 
  268.                 DeletePort (diskport); 
  269.         if (win) 
  270.                 CloseWindow (win); 
  271.         if (GfxBase) 
  272.                 CloseLibrary (GfxBase); 
  273.         if (IntuitionBase) 
  274.                 CloseLibrary (IntuitionBase); 
  275.  
  276. die (str) 
  277. UBYTE *str; 
  278.         errmsg.IText = str; 
  279.         AutoRequest (win, &errmsg, NULL, &ok, NULL, NULL, 
  280.                      TextLength (rp, str, (long) strlen (str)) + 40, 46L); 
  281.         closestuff (); 
  282.         exit (100); 
  283.  
  284. /* 
  285.  * The following routines were stolen from an RKM example by Bob Peck and 
  286.  * hacked up a bit. 
  287.  */ 
  288.  
  289. GetSector (sector) 
  290. long sector; 
  291.         LONG offset = sector * BLOCKSIZE; 
  292.  
  293.         diskreq -> iotd_Req.io_Length = BLOCKSIZE;       
  294.         diskreq -> iotd_Req.io_Data = (APTR) diskbuffer;  
  295.                 /* show where to put the data when read */ 
  296.         diskreq -> iotd_Req.io_Command = ETD_READ; 
  297.                 /* check that disk not changed before reading */ 
  298.         diskreq -> iotd_Count = diskchangecount; 
  299.          
  300.         /* convert from cylinder, head, sector to byte-offset value to get 
  301.          * right one (as dos and everyone else sees it)...*/ 
  302.          
  303.         /* driver reads one CYLINDER at a time (head does not move for 
  304.          * 22 sequential sector reads, or better-put, head doesnt move for 
  305.          * 2 sequential full track reads.) 
  306.          */ 
  307.          
  308.         diskreq -> iotd_Req.io_Offset = offset; 
  309.         DoIO (diskreq); 
  310.         return (0); 
  311.  
  312. MotorOn()
  313.         /* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */ 
  314.         diskreq -> iotd_Req.io_Length = 1; 
  315.         /* this says motor is to be turned on */ 
  316.         diskreq -> iotd_Req.io_Command = TD_MOTOR; 
  317.         /* do something with the motor */ 
  318.         DoIO (diskreq); 
  319.         return (0); 
  320.  
  321. MotorOff() 
  322.         diskreq -> iotd_Req.io_Length = 0;       
  323.         /* says that motor is to be turned on */ 
  324.         diskreq -> iotd_Req.io_Command = TD_MOTOR;       
  325.         /* do something with the motor */ 
  326.         DoIO (diskreq); 
  327.         return (0); 
  328.